/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package cn.newtest.bi.collection.formula.antlr;

import org.antlr.runtime.EarlyExitException;
import org.antlr.runtime.FailedPredicateException;
import org.antlr.runtime.MismatchedNotSetException;
import org.antlr.runtime.MismatchedRangeException;
import org.antlr.runtime.MismatchedSetException;
import org.antlr.runtime.MismatchedTokenException;
import org.antlr.runtime.MismatchedTreeNodeException;
import org.antlr.runtime.MissingTokenException;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.runtime.UnwantedTokenException;

/**
 *
 *
 * @author <a href="mailto: chenjian@risesoft.net">陈健</a>
 * @version $Revision$
 * 
 */
public class AntlrExceptionTranslator {
	
	public static String translateParserExceptionMessage(RecognitionException e, String[] tokenNames) {
		String hdr = getErrorHeader(e);
		
		String msg = hdr;
		
		if (e instanceof UnwantedTokenException) {
			UnwantedTokenException ute = (UnwantedTokenException) e;
			String tokenName = "<unknown>";
			if (ute.expecting == Token.EOF) {
				tokenName = "EOF";
			} else {
				tokenName = tokenNames[ute.expecting];
			}
			msg += "输多了表达式： " + getTokenErrorDisplay(ute.getUnexpectedToken()) + "，应该是： " + tokenName;
		} else if (e instanceof MissingTokenException) {
			MissingTokenException mte = (MissingTokenException) e;
			String tokenName = "<unknown>";
			if (mte.expecting == Token.EOF) {
				tokenName = "EOF";
			} else {
				tokenName = tokenNames[mte.expecting];
			}
			
			if(tokenName.equals("endprog")){
				msg += "在 " + getTokenErrorDisplay(e.token)+" 前缺少表达式";
			}else{
				msg += "在 " + getTokenErrorDisplay(e.token)+" 后缺少对应的表达式： " + tokenName ;
			}
			
		} else if (e instanceof MismatchedTokenException) {
			MismatchedTokenException mte = (MismatchedTokenException) e;
			String tokenName = "<unknown>";
			if (mte.expecting == Token.EOF) {
				tokenName = "EOF";
			} else {
				tokenName = tokenNames[mte.expecting];
			}
			msg += "错误的输入 :" + getTokenErrorDisplay(e.token) + " 应该是: " + tokenName;
		} else if (e instanceof MismatchedTreeNodeException) {
			MismatchedTreeNodeException mtne = (MismatchedTreeNodeException) e;
			String tokenName = "<unknown>";
			if (mtne.expecting == Token.EOF) {
				tokenName = "EOF";
			} else {
				tokenName = tokenNames[mtne.expecting];
			}
			msg = "mismatched tree node: " + mtne.node + " expecting " + tokenName;
		} else if (e instanceof NoViableAltException) {
			NoViableAltException nvae = (NoViableAltException) e;
			msg += "不应该出现： " + getTokenErrorDisplay(e.token);
		} else if (e instanceof EarlyExitException) {
			EarlyExitException eee = (EarlyExitException) e;
			msg += "在 " + getTokenErrorDisplay(e.token)+" 处不满足规则";
		} else if (e instanceof MismatchedSetException) {
			MismatchedSetException mse = (MismatchedSetException) e;
			msg = "mismatched input " + getTokenErrorDisplay(e.token) + " expecting set " + mse.expecting;
		} else if (e instanceof MismatchedNotSetException) {
			MismatchedNotSetException mse = (MismatchedNotSetException) e;
			msg = "mismatched input " + getTokenErrorDisplay(e.token) + " expecting set " + mse.expecting;
		} else if (e instanceof FailedPredicateException) {
			FailedPredicateException fpe = (FailedPredicateException) e;
			msg = "rule " + fpe.ruleName + " failed predicate: {" + fpe.predicateText + "}?";
		}
		return msg;
	}
	
	public static String translateLexerExceptionMessage(RecognitionException e, String[] tokenNames) {
		String hdr = getErrorHeader(e);
		
		String msg = hdr;
		
		if ( e instanceof MismatchedTokenException ) {
			MismatchedTokenException mte = (MismatchedTokenException)e;
			msg += "mismatched character "+getCharErrorDisplay(e.c)+" expecting "+getCharErrorDisplay(mte.expecting);
		}
		else if ( e instanceof NoViableAltException ) {
			NoViableAltException nvae = (NoViableAltException)e;
			msg += "不应该出现： "+getCharErrorDisplay(e.c);
		}
		else if ( e instanceof EarlyExitException ) {
			EarlyExitException eee = (EarlyExitException)e;
			msg += "在 " + getCharErrorDisplay(e.c)+" 处不满足规则";
		}
		else if ( e instanceof MismatchedNotSetException ) {
			MismatchedNotSetException mse = (MismatchedNotSetException)e;
			msg += "mismatched character "+getCharErrorDisplay(e.c)+" expecting set "+mse.expecting;
		}
		else if ( e instanceof MismatchedSetException ) {
			MismatchedSetException mse = (MismatchedSetException)e;
			msg += "mismatched character "+getCharErrorDisplay(e.c)+" expecting set "+mse.expecting;
		}
		else if ( e instanceof MismatchedRangeException ) {
			MismatchedRangeException mre = (MismatchedRangeException)e;
			msg += "mismatched character "+getCharErrorDisplay(e.c)+" expecting set "+
				  getCharErrorDisplay(mre.a)+".."+getCharErrorDisplay(mre.b);
		}
//		else {
//			msg = super.getErrorMessage(e, tokenNames);
//		}
		return msg;
	}

	private static String getTokenErrorDisplay(Token t) {
		String s = t.getText();
		if ( s==null ) {
			if ( t.getType()==Token.EOF ) {
				s = "<EOF>";
			}
			else {
				s = "<"+t.getType()+">";
			}
		}
		s = s.replaceAll("\n","\\\\n");
		s = s.replaceAll("\r","\\\\r");
		s = s.replaceAll("\t","\\\\t");
		return "'"+s+"'";
	}
	
	private static String getCharErrorDisplay(int c) {
		String s = String.valueOf((char)c);
		switch ( c ) {
			case Token.EOF :
				s = "<EOF>";
				break;
			case '\n' :
				s = "\\n";
				break;
			case '\t' :
				s = "\\t";
				break;
			case '\r' :
				s = "\\r";
				break;
		}
		return "'"+s+"'";
	}
	
	public static String getErrorHeader(RecognitionException e){
		return "在(行:"+e.line+"列:"+e.charPositionInLine+")出现错误，";
	}
}
